import axios from "axios";
import type { AxiosInstance, AxiosRequestConfig, AxiosResponse } from "axios";
import { ElMessage } from "element-plus";

export interface ApiResponse<T = any> {
  code: number;
  data: T;
  message: string;
}

class HttpRequest {
  private instance: AxiosInstance;
  private baseURL: string;

  constructor(baseURL: string) {
    this.baseURL = baseURL;
    this.instance = axios.create({
      baseURL,
      timeout: 10000,
      headers: {
        "Content-Type": "application/json;charset=UTF-8",
      },
    });

    this.initInterceptors();
  }

  /**
   * 初始化拦截器
   */
  private initInterceptors(): void {
    // 请求拦截器
    this.instance.interceptors.request.use(
      (config) => {
        // 添加token
        const token =
          localStorage.getItem("token") || sessionStorage.getItem("token");
        if (token && config.headers) {
          config.headers.Authorization = `Bearer ${token}`;
        }

        // 添加时间戳防止缓存
        if (config.method === "get") {
          config.params = {
            ...config.params,
            _t: Date.now(),
          };
        }

        console.log("请求发送：", config);
        return config;
      },
      (error) => {
        console.error("请求错误：", error);
        return Promise.reject(error);
      }
    );

    // 响应拦截器
    this.instance.interceptors.response.use(
      (response: AxiosResponse<ApiResponse>) => {
        console.log("响应接收：", response);

        const { data } = response;

        // 根据业务状态码处理
        if (data.code === 200) {
          return Promise.resolve(response);
        } else if (data.code === 401) {
          // token 过期
          ElMessage.error("登录已过期，请重新登录");
          localStorage.removeItem("token");
          sessionStorage.removeItem("token");
          // 可以在这里跳转到登录页
          window.location.href = "/login";
          return Promise.reject(new Error("Token expired"));
        } else {
          ElMessage.error(data.message || "请求失败");
          return Promise.reject(new Error(data.message));
        }
      },
      (error) => {
        console.error("响应错误：", error);

        if (error.response) {
          const { status, statusText } = error.response;

          switch (status) {
            case 400:
              ElMessage.error("请求参数错误");
              break;
            case 401:
              ElMessage.error("未授权，请重新登录");
              localStorage.removeItem("token");
              sessionStorage.removeItem("token");
              window.location.href = "/login";
              break;
            case 403:
              ElMessage.error("拒绝访问");
              break;
            case 404:
              ElMessage.error("请求的资源不存在");
              break;
            case 500:
              ElMessage.error("服务器内部错误");
              break;
            default:
              ElMessage.error(`请求失败: ${status} ${statusText}`);
          }
        } else if (error.request) {
          ElMessage.error("网络请求失败，请检查网络连接");
        } else {
          ElMessage.error("请求配置错误");
        }

        return Promise.reject(error);
      }
    );
  }

  /**
   * GET 请求
   */
  public async get<T = any>(
    url: string,
    config?: AxiosRequestConfig
  ): Promise<ApiResponse<T>> {
    const response = await this.instance.get(url, config);
    return response.data;
  }

  /**
   * POST 请求
   */
  public async post<T = any>(
    url: string,
    data?: any,
    config?: AxiosRequestConfig
  ): Promise<ApiResponse<T>> {
    const response = await this.instance.post(url, data, config);
    return response.data;
  }

  /**
   * PUT 请求
   */
  public async put<T = any>(
    url: string,
    data?: any,
    config?: AxiosRequestConfig
  ): Promise<ApiResponse<T>> {
    const response = await this.instance.put(url, data, config);
    return response.data;
  }

  /**
   * DELETE 请求
   */
  public async delete<T = any>(
    url: string,
    config?: AxiosRequestConfig
  ): Promise<ApiResponse<T>> {
    const response = await this.instance.delete(url, config);
    return response.data;
  }

  /**
   * PATCH 请求
   */
  public async patch<T = any>(
    url: string,
    data?: any,
    config?: AxiosRequestConfig
  ): Promise<ApiResponse<T>> {
    const response = await this.instance.patch(url, data, config);
    return response.data;
  }

  /**
   * 上传文件
   */
  public async upload<T = any>(
    url: string,
    file: File,
    config?: AxiosRequestConfig
  ): Promise<ApiResponse<T>> {
    const formData = new FormData();
    formData.append("file", file);

    const response = await this.instance.post(url, formData, {
      ...config,
      headers: {
        "Content-Type": "multipart/form-data",
        ...config?.headers,
      },
    });
    return response.data;
  }
}

// 创建实例
// 在开发环境下，mock服务运行在当前开发服务器上，不需要/api前缀
const isDev = import.meta.env.DEV;
const baseURL = isDev
  ? window.location.origin // 使用当前页面的origin (http://localhost:3000)
  : import.meta.env.VITE_API_BASE_URL || "http://localhost:8080/api";

const request = new HttpRequest(baseURL);

export default request;
